home *** CD-ROM | disk | FTP | other *** search
/ BCI NET 2 / BCI NET 2.iso / archives / programming / c / hce.lha / HCE / LibSource / clib / Misc / src / System0.a < prev    next >
Encoding:
Text File  |  1992-09-02  |  7.4 KB  |  277 lines

  1. *
  2. * System0.asm - invoke system's command processor
  3. *
  4. * Copyright (C) by Ralph Babel, Guru Meditation Network,
  5. * Falkenweg 3, D-6204 Taunusstein, West-Germany
  6. *
  7. * This piece of code may be used as part of any product as
  8. * long as the source code for the complete program can be
  9. * obtained free of charge (except for a small copying fee)
  10. * and this copyright notice is left unchanged.
  11. *
  12. * Bug reports and improved versions appreciated.
  13. *
  14. * 20-Jul-1987 created original version
  15. * 11-Jan-1988 now based on "official" information only
  16. *
  17.  
  18.         nolist
  19.  
  20.         include "exec/types.i"
  21.         include "libraries/dos.i"
  22.         include "libraries/dosextens.i"
  23.         include "extern/exec.i"
  24.         include "extras/asm.i"
  25.  
  26.         list
  27.  
  28. *
  29. * LONG System0(name, seglist, args)
  30. * char *name;
  31. * BPTR seglist;
  32. * char *args;
  33. *
  34.  
  35.         xdef    _System0
  36.         xref    _DOSBase
  37.  
  38. * parameter offsets & stack
  39.  
  40. SAVED_REGS      reg     a2-a6/d2-d3
  41.  
  42. DELTA           equ     7*4
  43.  
  44. ARG_NAME        equ     4+DELTA
  45. ARG_SEGLIST     equ     8+DELTA
  46. ARG_ARGS        equ     12+DELTA
  47.  
  48. * additional return codes
  49.  
  50. NO_CLI  equ     -1
  51. NO_MEM  equ     -2
  52.  
  53. * local constants
  54.  
  55. MAXBSTR equ     255
  56. LF      equ     10
  57.  
  58. * register usage
  59.  
  60. REG_Result      equr    d3
  61. REG_Process     equr    a2      ;may not be A4, see below!
  62. REG_CLI         equr    a3
  63. REG_CIS         equr    a4      ;may not be A3, see below!
  64. REG_PrevStack   equr    a5
  65.  
  66. * local stack frame
  67.  
  68.  STRUCTURE      StackFrame,0
  69.         STRUCT  sf_CommandName,MAXBSTR+1        ;BSTR, length byte!
  70.         STRUCT  sf_CommandArgs,MAXBSTR+1        ;not a BSTR, LF-terminated!
  71.  
  72.         APTR    sf_PrevStack
  73.  
  74.         APTR    sf_SaveReturnAddr
  75.         BPTR    sf_SaveModule
  76.         BPTR    sf_SaveCommandName
  77.  
  78.         APTR    sf_StackBase
  79.         LONG    sf_StackSize
  80.         LONG    sf_PushSize
  81.  
  82.         APTR    sf_Process
  83.         APTR    sf_CLI
  84.         APTR    sf_CIS
  85.  
  86.         BPTR    sf_SCB_Buf
  87.         LONG    sf_SCB_Pos
  88.         LONG    sf_SCB_End
  89.  
  90.         LABEL   sf_SIZEOF
  91.  
  92. * entry point
  93.  
  94. _System0:
  95.         movem.l SAVED_REGS,-(sp)
  96.  
  97.         moveq   #NO_CLI,REG_Result      ;ERROR - not a CLI task
  98.  
  99.         movea.l AbsExecBase,REG_SysBase
  100.         suba.l  a1,a1
  101.         callsys FindTask        ;find own task
  102.         movea.l d0,REG_Process
  103.         move.l  pr_CLI(REG_Process),d0
  104.         beq     quit0
  105.  
  106. * build local stack frame & save some values
  107.  
  108.         lsl.l   #2,d0   ;BPTR to machine pointer
  109.         movea.l d0,REG_CLI
  110.  
  111.         movea.l sp,REG_PrevStack        ;save old stack pointer
  112.         move.l  sp,d0
  113.         andi.b  #$fc,d0 ;make SP longword-aligned for BPTRs
  114.         movea.l d0,sp
  115.         suba.w  #sf_SIZEOF,sp
  116.  
  117.         move.l  REG_PrevStack,sf_PrevStack(sp)
  118.         move.l  REG_Process,sf_Process(sp)
  119.         move.l  REG_CLI,sf_CLI(sp)
  120.  
  121.         move.l  pr_ReturnAddr(REG_Process),sf_SaveReturnAddr(sp)
  122.  
  123. * allocate space for stack
  124.  
  125.         moveq   #NO_MEM,REG_Result      ;ERROR - no memory for STACK
  126.  
  127.         move.l  cli_DefaultStack(REG_CLI),d0    ;in longwords for "VEC"
  128.         lsl.l   #2,d0
  129.         move.l  d0,sf_PushSize(sp)
  130.         addq.l  #4,d0   ;one additional longword
  131.         move.l  d0,sf_StackSize(sp)
  132.         moveq   #0,d1   ;intentionally NOT "MEMF_PUBLIC"!
  133.         callsys AllocMem
  134.         tst.l   d0
  135.         beq     quit1
  136.  
  137.         move.l  d0,sf_StackBase(sp)     ;save result
  138.  
  139. * save old command pointer, build new BCPL command name
  140.  
  141.         move.l  cli_CommandName(REG_CLI),sf_SaveCommandName(sp)
  142.  
  143.         movea.l ARG_NAME(REG_PrevStack),a0      ;first parameter to "System0()"
  144.         lea     sf_CommandName+1(sp),a1 ;first char location for BSTR
  145.         move.l  a1,d0
  146.         lsr.l   #2,d0   ;will ignore (+1), BPTR as result
  147.         move.l  d0,cli_CommandName(REG_CLI)
  148.  
  149.         move.w  #MAXBSTR,d0
  150.         bra.s   2$
  151.  
  152. 1$      move.b  d1,(a1)+
  153. 2$      move.b  (a0)+,d1
  154.         dbeq    d0,1$
  155.  
  156.         suba.l  ARG_NAME(REG_PrevStack),a0      ;subtract original source
  157.         move.l  a0,d0
  158.         subq.l  #1,d0   ;terminating null-byte
  159.         move.b  d0,sf_CommandName(sp)   ;to first location in BSTR
  160.  
  161. * save contents of Current Input Stream
  162.  
  163.         move.l  pr_CIS(REG_Process),d0
  164.         lsl.l   #2,d0
  165.         movea.l d0,REG_CIS      ;contains APTR to CIS
  166.         move.l  REG_CIS,sf_CIS(sp)
  167.  
  168.         move.l  fh_Buf(REG_CIS),sf_SCB_Buf(sp)
  169.         move.l  fh_Pos(REG_CIS),sf_SCB_Pos(sp)
  170.         move.l  fh_End(REG_CIS),sf_SCB_End(sp)
  171.  
  172. * convert argument to LF-terminated string
  173.  
  174.         movea.l ARG_ARGS(REG_PrevStack),a0      ;third argument to "System0()"
  175.         lea     sf_CommandArgs(sp),a1   ;first buffer location
  176.         move.l  a1,d0
  177.         lsr.l   #2,d0   ;make buffer pointer a BPTR
  178.         move.l  d0,fh_Buf(REG_CIS)
  179.  
  180.         move.w  #MAXBSTR,d0     ;leave some room for terminating LF
  181.         bra.s   4$
  182.  
  183. 3$      move.b  d1,(a1)+
  184. 4$      move.b  (a0)+,d1
  185.         dbeq    d0,3$
  186.  
  187.         move.b  #LF,(a1)
  188.         suba.l  ARG_ARGS(REG_PrevStack),a0      ;subtract first position
  189.         move.l  a0,d0   ;do NOT subtract, LF need this byte
  190.  
  191. * setup start/end indices in Stream Control Block
  192.  
  193.         clr.l   fh_Pos(REG_CIS)
  194.         move.l  d0,fh_End(REG_CIS)
  195.  
  196. * misc setup
  197.  
  198.         clr.l   pr_Result2(REG_Process) ;clear secondary result
  199.  
  200.         moveq   #0,d0
  201.         move.l  #SIGBREAKF_CTRL_C,d1
  202.         callsys SetSignal       ;clear CTRL-C flag
  203.  
  204. * handle seglist and start address
  205.  
  206.         move.l  cli_Module(REG_CLI),sf_SaveModule(sp)
  207.  
  208.         move.l  ARG_SEGLIST(REG_PrevStack),d0   ;second argument to "System0()"
  209.         move.l  d0,cli_Module(REG_CLI)
  210.         lsl.l   #2,d0
  211.         movea.l d0,a3   ;make it a machine pointer in A3
  212.  
  213. * setup processor registers & C-interface
  214.  
  215.         lea     sf_CommandArgs(sp),a0
  216.         move.l  fh_End(REG_CIS),d0
  217.  
  218. * setup processor registers, BCPL-interface, stack & return address for "Exit()"
  219.  
  220.         movea.l sf_StackBase(sp),a1     ;BCPL stack, low end
  221.         move.l  sf_PushSize(sp),d2
  222.         lea     4(a1,d2.l),a4   ;must not destroy REG_Process!
  223.         move.l  sp,-(a4)        ;previous stack frame
  224.         move.l  d2,-(a4)        ;stack size in bytes
  225.         move.l  a4,pr_ReturnAddr(REG_Process)
  226.         movea.l a4,sp
  227.  
  228.         movea.l _DOSBase,a4     ;large data memory model!
  229.         movem.l dl_A2(a4),a2/a5/a6
  230.  
  231. * now call the command at its entry point
  232.  
  233.         jsr     4(a3)   ;code starts one longword behind segment pointer
  234.  
  235.         move.l  d0,REG_Result   ;save return code
  236.  
  237. * get old stackframe & reload old register contents
  238.  
  239.         movea.l 4(sp),sp        ;old stack frame
  240.  
  241.         movea.l sf_Process(sp),a0
  242.         move.l  sf_SaveReturnAddr(sp),pr_ReturnAddr(a0)
  243.  
  244.         movea.l sf_CLI(sp),a0
  245.         move.l  sf_SaveCommandName(sp),cli_CommandName(a0)
  246.         move.l  sf_SaveModule(sp),cli_Module(a0)
  247.  
  248. * restore original contents of Current Input Stream
  249.  
  250.         movea.l sf_CIS(sp),a0
  251.         lea     sf_CommandArgs(sp),a1
  252.         move.l  a1,d0
  253.         lsr.l   #2,d0
  254.         cmp.l   fh_Buf(a0),d0   ;still the same?
  255.         bne.s   5$      ;no: don't restore
  256.         move.l  sf_SCB_Buf(sp),fh_Buf(a0)
  257. 5$      move.l  sf_SCB_Pos(sp),fh_Pos(a0)
  258.         tst.l   fh_End(a0)      ;end index set?
  259.         beq.s   6$      ;no: don't restore
  260.         move.l  sf_SCB_End(sp),fh_End(a0)
  261.  
  262. * free temporary stack
  263.  
  264. 6$      movea.l AbsExecBase,REG_SysBase
  265.         movea.l sf_StackBase(sp),a1
  266.         move.l  sf_StackSize(sp),d0
  267.         callsys FreeMem
  268.  
  269. quit1   movea.l sf_PrevStack(sp),sp     ;UNLINK local variables
  270.  
  271. quit0   move.l  REG_Result,d0
  272.  
  273.         movem.l (sp)+,SAVED_REGS
  274.         rts
  275.  
  276.         end
  277.